package com.bz.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bz.common.BusinessException;
import com.bz.common.CommonHeader;
import com.bz.common.PageInfo;
import com.bz.common.UserConfig;
import com.bz.dao.RoleDao;
import com.bz.dao.UserDao;
import com.bz.dao.UserRoleDao;
import com.bz.entity.UserEntity;
import com.bz.entity.UserRoleEntity;
import com.bz.security.ThreadLocalUtils;
import com.bz.service.IUserService;

@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserDao     userDao;

    @Autowired
    private RoleDao     roleDao;

    @Autowired
    private UserRoleDao userRoleDao;

    @Override
    public PageInfo<UserEntity> getUser(PageInfo page, String searchText, String roleId) {

        LambdaQueryWrapper<UserEntity> query = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(searchText)) {
            query.and(s -> s.like(UserEntity::getName, searchText).or().like(UserEntity::getPhone, searchText));
        }
        if (StringUtils.isNotEmpty(roleId)) {
            Map<String, Object> parMap = new HashMap<>();
            parMap.put("role_id", roleId);
            List<UserRoleEntity> rs = userRoleDao.selectByMap(parMap);
            if (!CollectionUtils.isEmpty(rs)) {
                List<Long> uids = rs.stream().map(UserRoleEntity::getUserId).collect(Collectors.toList());
                query.in(UserEntity::getId, uids);
            }
        }

        query.orderByDesc(UserEntity::getUpdateDate);

        PageInfo<UserEntity> pageinfo = userDao.selectPage(page, query);

        if (null == pageinfo) {
            return pageinfo;
        }

        List<UserEntity> ulist = pageinfo.getRecords();

        // 获取操作权限
        if (!CollectionUtils.isEmpty(ulist)) {
            for (UserEntity u : ulist) {

                // 设置角色
                Map<String, Object> parMap1 = new HashMap<>();
                parMap1.put("userId", u.getId());
                u.setRoleList(roleDao.getUserRole(parMap1));
            }
        }
        return pageinfo;
    }

    @Override
    public List<UserEntity> getUser(Map<String, Object> parMap) {
        return userDao.selectByMap(parMap);
    }

    @Override
    @Transactional
    public void insert(UserEntity userDto, String roles) {

        userDao.insert(userDto);
        CommonHeader lu = ThreadLocalUtils.get();
        for (String role : roles.split(",")) {
            UserRoleEntity userRoleDto = new UserRoleEntity();
            userRoleDto.setUserId(userDto.getId());
            userRoleDto.setRoleId(Long.valueOf(role));

            userRoleDto.setCreateBy(lu.getUsername());
            userRoleDto.setUpdateBy(lu.getUsername());
            userRoleDto.setCreateDate(new Date());
            userRoleDao.insert(userRoleDto);
        }
    }

    @Override
    @Transactional
    public void update(UserEntity userDto, String roles) {

        userDao.updateById(userDto);

        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put("user_id", userDto.getId());
        userRoleDao.deleteByMap(columnMap);

        CommonHeader lu = ThreadLocalUtils.get();

        if (StringUtils.isNotEmpty(roles)) {
            for (String role : roles.split(",")) {
                UserRoleEntity userRoleDto = new UserRoleEntity();
                userRoleDto.setUserId(userDto.getId());
                userRoleDto.setRoleId(Long.valueOf(role));

                userRoleDto.setCreateBy(lu.getUsername());
                userRoleDto.setUpdateBy(lu.getUsername());
                userRoleDto.setCreateDate(new Date());
                userRoleDao.insert(userRoleDto);
            }
        }

    }

    @Override
    public void updateStatus(Long id, String status) {

        UserEntity ue = userDao.selectById(id);
        if (null == ue) {
            return;
        }
        UserEntity lu = UserConfig.getLoginUser();
        LambdaUpdateWrapper<UserEntity> lambdaUpdateWrapper = new UpdateWrapper<UserEntity>().lambda();
        lambdaUpdateWrapper.set(UserEntity::getStatus, status).set(UserEntity::getUpdateBy, lu.getUsername())
            .eq(UserEntity::getId, id);
        userDao.update(null, lambdaUpdateWrapper);

    }

    @Override
    @Transactional
    public void delete(Long id) {

        // 删除用户
        userDao.deleteById(id);

        // 删除角色
        Map<String, Object> columnMap = new HashMap<>();
        columnMap.put("user_id", id);
        userRoleDao.deleteByMap(columnMap);

    }

    @Override
    public void updatePassword(String oldPassword, String password) {
        UserEntity lu = UserConfig.getLoginUser();
        UserEntity ue = userDao.selectById(lu.getId());
        if (null == ue) {
            throw new BusinessException("数据不存在");
        }
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        if (!encoder.matches(oldPassword, ue.getPassword())) {
            throw new BusinessException("原密码输入不正确！");
        }

        ue.setPassword(encoder.encode(password));
        ue.setUpdateBy(lu.getUsername());
        userDao.updateById(ue);

    }

    @Override
    public void setPassword(Long id, String password) {
        UserEntity ue = userDao.selectById(id);
        if (null == ue) {
            throw new BusinessException("数据不存在");
        }
        UserEntity lu = UserConfig.getLoginUser();
        ue.setPassword(password);
        ue.setUpdateBy(lu.getUsername());
        userDao.updateById(ue);

    }

    @Override
    @Transactional
    public void updateInfo(UserEntity userDto) {

        UserEntity authUserDto = UserConfig.getLoginUser();

        // 校验是否存在
        UserEntity ue = userDao.selectById(authUserDto.getId());
        if (null == ue) {
            throw new BusinessException("数据不存在");
        }

        ue.setName(userDto.getName());
        ue.setPhone(userDto.getPhone());

        UserEntity lu = UserConfig.getLoginUser();
        userDto.setUpdateBy(lu.getUsername());
        userDao.updateById(ue);
    }

    @Override
    public UserEntity info(Long id) {
        UserEntity ue = userDao.selectById(id);
        if (null == ue) {
            return null;
        }

        UserEntity u = JSON.parseObject(JSON.toJSONString(ue), UserEntity.class);
        // 设置角色
        Map<String, Object> parMap1 = new HashMap<>();
        parMap1.put("userId", u.getId());
        u.setRoleList(roleDao.getUserRole(parMap1));

        return u;
    }

    @Override
    public List<UserEntity> getAll(QueryWrapper<UserEntity> query) {
        return userDao.selectList(query);
    }
}
